#include <stdio.h>
#include <mpx_supt.h>
#include <string.h>

PCB *pHeadR;
PCB *pTailR;
PCB *pHeadB;
PCB *pTailB;
int count;

void enqueueBlocked(PCB element)
{
	if(count == 0)   //First element
	{
		pHeadB = &element;   //first element is at the head of queue
		pTailB = &element;   //first element is at the tail of queue
		count++;   
	}
	
	else
	{
		element.setNext() = pTailB;   //set next to the tail element
		element.setPrev() = null;    //set previous to null
		pTailB = &element;            //set tail pointer to the element
		count++;
	}
}

PCB dequeueBlocked()
{
	PCB *pTemp = null;
	if(count == 0)
	{
		printf("The queue is empty.");
	}
	
	else
	{
		pTemp = pHeadB;               //Hold the value to be dequed in temp pointer
		pHeadB = (*pTemp).getPrev();     //Assign new head to previous PCB
		count--;
	}
	
	return *pTemp;             //Return head PCB
}
		
void enqueueReady(PCB element)
{
	if(count == 0)   //First element
	{
		pHeadR = &element;   //first element is at the head of queue
		pTailR = &element;   //first element is at the tail of queue
		count++;   
	}
	
	else
	{
		PCB *pBehind = &(searchPriority(element.getPriority())); //search to find element priority
		
		if(pBehind == pTailR)       //If element has lowest priority
		{
			element.setNext() = (*pTailR).getNext();  //set element's next to tail's next
			element.setPrev() = null;               //no previous node
			pTailR = &element;  			//set tail pointer to the element
			count++;
		}
		
		else
		{
			element.setPrev() = pBehind;    //set previous to the element behind the new element
			element.setNext() = (*pBehind).setNext();  //set next to behind's next
			(*pBehind).setNext() = &element;    //set behind element's next to the new element
			count++;
		}
	}
}	

PCB dequeueReady()
{
	PCB *pTemp = null;
	if(count == 0)
	{
		printf("The queue is empty.");
	}
	
	else
	{
		pTemp = pHeadR;               //Hold the value to be dequed in temp pointer
		pHeadR = (*pTemp).getPrev();     //Assign new head to previous PCB
		count--;
	}
	
	return *pTemp;             //Return head PCB
}

PCB searchPriority(int newPriority)
{
	PCB *pElementBehindNewElement;
	PCB *pTemp = pHeadR;
	
	if(newPriority > (*pHeadR).getPriority())   //Highest Priority
	{
		pElementBehindNewElement = pHeadR;
	}
	
	else if(newPriority < (*pTailR).getPriority())  //Lowest priority
	{
		pElementBehindNewElement = pTailR;
	}
	
	else
	{
		while(newPriority < (*pTemp).getPriority())   //check if new element's priority is less than temp's
		{
			pTemp = (*pTemp).getPrev();  //Search backwards from head
		}
		
		pElementBehindNewElement = pTemp;
	}
	
	return *pElementBehindNewElement;
}

PCB* searchPCBbyName(char[] name)
{
	PCB *pTemp = pHeadR;   //Starts with seaching at the head of the ready queue
	int notHere = 0;     //Indicator as to whether or not the PCB is found
	
	while((strncmp((*pTemp).getName(), name, 50) == 1) || (notHere == 1)) //Search through ready queue
	{
		if(pTemp == pTailR) { notHere = 1;}  //At end of queue
		
		else
		{pTemp = (*pTemp).getPrev();}  //Not at end, keep looking
	}
	
	if(notHere == 1)   //Wasn't found in ready queue
	{
		notHere = 0;   //Reset notHere indicator
		pTemp = pHeadB;   //Set temp pointer to the blocked queue head
		
		while((strncmp((*pTemp).getName(), name, 50) == 1) || (notHere == 1)) //Search through blocked queue
		{
			if(pTemp == pTailB) { notHere = 1;}  //At end of queue
		
			else
			{pTemp = (*pTemp).getPrev();}  //Not at end, keep looking
		}
	}
	
	if(notHere == 1)         //Wasn't found in either queue
	{
		printf("%s was not found.\n", name);
		return 0;
	}
	
	return pTemp;
}	
	